/*
 * config.cpp
 *
 *  Created on: 2011-4-27
 *      Author: chenl
 */

#include "config.h"
#include "common/common_err.h"
#include "common/common_util.h"
#include "ps_error.h"
#include "global.h"
#include <string.h>

#define TAGNAME_LOGCONF			"logconf"
#define TAGNAME_SYSCONF			"sysconf"
#define TAGNAME_PSCONF			"psconf"

#define TAGNAME_LOGGER			"logger"
#define TAGNAME_PARAM			"param"
#define TAGNAME_LIMITS			"limits"

#define ATTRIBUTE_LEVEL			"level"
#define ATTRIBUTE_MAXLOGFILESIZE "maxlogfilesize"

#define ATTRIBUTE_MAXTASK		"maxtask"

#define ATTRIBUTE_HZ			"hz"

#define ATTRIBUTE_SCHEDULER		"scheduler"
#define ATTRIBUTE_SLOWERTIMES	"slowertimes"



CParamConfig::CParamConfig()
: logEngine(DEFAULT_PS_LOGPREFIX, LOGLEVEL), bReload_(false)
{
	memset(&logconf_, 0 ,sizeof(logconf_));
	memset(&sysconf_, 0, sizeof(sysconf_));
	memset(&psconf_, 0, sizeof(psconf_));
}

int32_t CParamConfig::Initialize()
{
	if (bReload_)
	{
		memset(&logconf_, 0 ,sizeof(logconf_));
		memset(&sysconf_, 0, sizeof(sysconf_));
		memset(&psconf_, 0, sizeof(psconf_));
	}

	TiXmlDocument doc(CONFIG_FILE);
	doc.LoadFile(TIXML_ENCODING_UTF8);

	TiXmlElement* pRoot = NULL;
	pRoot = doc.FirstChildElement();
	if (NULL == pRoot)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load root node failed!");
		return E_PS_MISCONFIGED;
	}

	TiXmlElement* plogconf = NULL;
	plogconf = pRoot->FirstChildElement(TAGNAME_LOGCONF);
	if (NULL == plogconf)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load TAGNAME_LOG failed!");
		return E_PS_MISCONFIGED;
	}
	int32_t ret = _LoadLogConf(plogconf);
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load log config failed!(ErrorCode=0x%08x)\n", ret);
		return ret;
	}

	TiXmlElement* pSysConf = NULL;
	pSysConf = pRoot->FirstChildElement(TAGNAME_SYSCONF);
	if (NULL == pSysConf)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load TAGNAME_SYSCONF failed!");
		return E_PS_MISCONFIGED;
	}
	ret = _LoadSysConf(pSysConf);
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load sysconf failed!(ErrorCode=0x%08x)\n", ret);
		return ret;
	}

	TiXmlElement* pPSConf = NULL;
	pPSConf = pRoot->FirstChildElement(TAGNAME_PSCONF);
	if (NULL == pPSConf)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load TAGNAME_PSCONF failed!");
		return E_PS_MISCONFIGED;
	}
	ret = _LoadPSConf(pPSConf);
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load psconf failed!(ErrorCode=0x%08x)", ret);
		return ret;
	}
	return S_OK;
}

int32_t CParamConfig::Reload()
{
	bReload_ = true;
	return Initialize();
}

int32_t CParamConfig::_LoadLogConf(TiXmlElement* plogconf)
{
	assert(NULL != plogconf);

	if (unlikely(NULL == plogconf))
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "NULL pointer(plogconf) in CParamConfig::_Loadlogconf()!");
		return E_NULLPOINTER;
	}

	TiXmlElement* pLogger = plogconf->FirstChildElement(TAGNAME_LOGGER);
	if (NULL == pLogger)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load TAGNAME_LIMITS failed in CParamConfig::_Loadlogconf()!");
		return E_PS_MISCONFIGED;
	}
	const char* pszValue = NULL;
	pszValue = pLogger->Attribute(ATTRIBUTE_LEVEL);
	if (NULL == pszValue)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load ATTRIBUTE_LEVEL failed in CParamConfig::_Loadlogconf()!");
		return E_PS_MISCONFIGED;
	}
	LogLevel logLevel = StrToLogLevel(pszValue);
	if (enmLogLevel_INVALID == logLevel)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "ATTRIBUTE_LEVEL ==  enmLogLevel_INVALID in CParamConfig::_Loadlogconf()!");
		return E_PS_MISCONFIGED;
	}
	logconf_.logLevel = logLevel;

	pszValue = pLogger->Attribute(ATTRIBUTE_MAXLOGFILESIZE);
	if (NULL == pszValue)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load ATTRIBUTE_LEVEL failed in CParamConfig::_Loadlogconf()!");
		return E_PS_MISCONFIGED;
	}
	sscanf(pszValue, "0x%08x", &logconf_.maxLogFileSize);
	return S_OK;
}

int32_t CParamConfig::_LoadSysConf(TiXmlElement* pSysConf)
{
	assert(NULL != pSysConf);

	if (unlikely(NULL == pSysConf))
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "NULL pointer(pSysConf) in CParamConfig::_LoadSysConf()!");
		return E_NULLPOINTER;
	}

	TiXmlElement* pLimits = pSysConf->FirstChildElement(TAGNAME_LIMITS);
	if (NULL == pLimits)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load TAGNAME_LIMITS failed in CParamConfig::_LoadSysConf()!");
		return E_PS_MISCONFIGED;
	}
	const char* pszValue = NULL;
	pszValue =pLimits->Attribute(ATTRIBUTE_MAXTASK, &sysconf_.nMaxTask);
	if (NULL == pszValue)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load ATTRIBUTE_MAXTASK failed in CParamConfig::_LoadSysConf()!");
		return E_PS_MISCONFIGED;
	}

	TiXmlElement* pParam = pSysConf->FirstChildElement(TAGNAME_PARAM);
	if (NULL == pParam)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load TAGNAME_PARAM failed in CParamConfig::_LoadSysConf()!");
		return E_PS_MISCONFIGED;
	}

	pszValue =pParam->Attribute(ATTRIBUTE_HZ, &sysconf_.HZ);
	if (NULL == pszValue)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load ATTRIBUTE_HZ failed in CParamConfig::_LoadSysConf()!");
		return E_PS_MISCONFIGED;
	}
	return S_OK;
}

int32_t CParamConfig::_LoadPSConf(TiXmlElement* pPSConf)
{
	assert(NULL != pPSConf);

	if (unlikely(NULL == pPSConf))
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "NULL pointer(pPSConf) in CParamConfig::_LoadPSConf()!");
		return E_NULLPOINTER;
	}

	TiXmlElement* pParam = pPSConf->FirstChildElement(TAGNAME_PARAM);
	if (NULL == pParam)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load TAGNAME_PARAM failed in CParamConfig::_LoadPSConf()!");
		return E_PS_MISCONFIGED;
	}
	const char* pszValue = NULL;
	pszValue = pParam->Attribute(ATTRIBUTE_SCHEDULER, &psconf_.scheduler);
	if (NULL == pszValue)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load ATTRIBUTE_SCHEDULER failed in CParamConfig::_LoadPSConf()!");
		return E_PS_MISCONFIGED;
	}

	pszValue = pParam->Attribute(ATTRIBUTE_SLOWERTIMES, &psconf_.slowerTimes);
	if (NULL == pszValue)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Load ATTRIBUTE_SLOWERTIMES failed in CParamConfig::_LoadPSConf()!");
		return E_PS_MISCONFIGED;
	}
	return S_OK;

}

